from portal.models import News, Package, Post, UserProfile
from django.contrib.auth.models import User
from datetime import datetime,timedelta
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from utils import log
from portal.forms import LoginForm, RegistrationForm, ProfileForm
import operator
import random, sha
from calendar import month_name

def main(request):
    #get all objects from the last 5 days
    #exclude ones marked as deleted or hidden
    news = list(News.recent.exclude(state="deleted").exclude(state="hidden"))
    packages = list(Package.recent.exclude(state="deleted").exclude(state="hidden"))
    posts = list(Post.recent.exclude(state="deleted").exclude(state="hidden"))
    objects = news + packages + posts
    #sort so we can handle the dates correctly in for loop
    sorted(objects,key=operator.attrgetter("date"))
    grouped_objects = []
    last_date = None
    obj = None
    for item in objects:
        #we take the date, and make append a dict in the list
        #we then add objects in that dict until we reach different
        #date, we create a new dict then that holds objects for that day
        date = item.date
        if last_date==None or last_date!=date:
            obj=dict(date=date,news=[],packages=[],posts=[])
            grouped_objects.append(obj)
        if isinstance(item,News):
            obj['news'].append(item)
        elif isinstance(item,Post):
            obj['posts'].append(item)
        elif isinstance(item,Package):
            obj['packages'].append(item)
        else:
            log.error("Tried to process weird object: %s"%str(item))
        last_date=date
            
    context = dict(content = grouped_objects)
    return render_to_response('portal/main.html', context, RequestContext(request))  
    
def archive(request, month, year):
    if month == "" and year == "":
        # month not specified, show list of months + years
        news_months = list(News.objects.dates('created_date', 'month'))
        packages_months = list(Package.objects.dates('created_date', 'month'))
        posts_months = list(Post.objects.dates('created_date', 'month'))
        objects = news_months + packages_months + posts_months
        objects.sort(reverse=True)
        # group months from all three tables
        distinct_months = [] # in form: [month_number, month_name, year]
        for item in objects:
            already_in = False
            for month in distinct_months:
                if month[0] == item.month:
                    already_in = True
            if already_in == False:
                distinct_months.append([item.month, month_name[item.month], item.year])
        context = {"list":True,"months":distinct_months}
    else:
        # set year to current if it's not specified in url
        if year == "":
            year = datetime.now().year
        news = list(News.objects.filter(created_date__year=year, created_date__month=month).order_by('-created_date'))
        packages = list(Package.objects.filter(created_date__year=year, created_date__month=month).order_by('-created_date'))
        posts = list(Post.objects.filter(created_date__year=year, created_date__month=month).order_by('-created_date'))
        # borrowed code from main() ;)
        objects = news + packages + posts
        sorted(objects,key=operator.attrgetter("date"))
        grouped_objects = []
        last_date = None
        obj = None
        for item in objects:
            date = item.date
            if last_date==None or last_date!=date:
                obj=dict(date=date,news=[],packages=[],posts=[])
                grouped_objects.append(obj)
            if isinstance(item,News):
                obj['news'].append(item)
            elif isinstance(item,Post):
                obj['posts'].append(item)
            elif isinstance(item,Package):
                obj['packages'].append(item)
            else:
                log.error("Tried to process weird object: %s"%str(item))
            last_date=date
        try:
            month = month_name[int(month)]
        except IndexError:
            pass
        context = {"list":False, "content":grouped_objects, "month":month, "year":year}
    return render_to_response('portal/archive.html', context, RequestContext(request))
    
def login(request):
    # go to last location after login
    if request.GET.has_key("next"):
        go_to = request.GET["next"]
    else:
        go_to = "/"
    # were there errors while trying to post
    if request.session.get("login_error", False):
        login_error = True
        del request.session["login_error"]
    else:
        login_error = False
    # create form
    f = LoginForm()
    context = {"go_to":go_to, "form":f, "login_error":login_error}
    return render_to_response('portal/login.html', context, RequestContext(request))

def register(request):
    context = {}
    if request.POST:
        if request.POST.has_key("registration"):
            # if registration form was posted
            f = RegistrationForm(request.POST)
        else:
            f = RegistrationForm()
    else:
        f = RegistrationForm()
    context = {"form":f}
    if f.is_valid():
        # save user
        new_user = f.save()
        
        # create activation key
        salt = sha.new(str(random.random())).hexdigest()[:5]
        activation_key = sha.new(salt+new_user.username).hexdigest()
        key_expires = datetime.today() + timedelta(days=4)
        
        # create new UserProfile (store activation key and when it expires)
        new_user_profile = UserProfile(user=new_user, activation_key=activation_key, key_expires=key_expires)
        new_user_profile.save()
        
        # send mail with confirmation link
        if request.META["SERVER_NAME"] == "localhost":
            activation_link = "localhost:8000"
        else:
            activation_link = request.META["SERVER_NAME"]
        subject = "Registracija na soup.zen.si"
        body = "Nekdo, upamo da vi, je registriral uporabnisko ime na strani soup.zen.si. Za potrditev registracije kliknite na naslednjo povezavo:\n\n\
http://%s/portal/activate/%s\n\n\
V primeru, da niste ustvarili novega uporabniskega imena na nasi spletni strani preprosto izbrisite to sporocilo.\n\n\
S spostovanjem,\n\
za ekipo Soup, vas usluzni e-postni kurir" % (activation_link, new_user_profile.activation_key)
        send_mail(subject, body, "registracija@soup.zen.si", [new_user.email])
        
        context["done"] = True

    return render_to_response('portal/register.html', context, RequestContext(request))
    
def activate(request, activation_key):
    # try to get user from UserProfile
    try:
        user_profile = UserProfile.objects.get(activation_key=activation_key)
    except UserProfile.DoesNotExist:
        return render_to_response('portal/activate.html', {"doesnt_exist":True}, RequestContext(request))
    # check expiration date
    user_account = user_profile.user
    if user_profile.key_expires < datetime.today():
        # date expired, delete User and UserProfile
        user_profile.delete()
        user_account.delete()
        return render_to_response('portal/activate.html', {"expired":True}, RequestContext(request))
    # set user active
    user_account.is_active = True
    user_account.save()
    return render_to_response('portal/activate.html', {"done":True}, RequestContext(request))
    
@login_required
def edit_profile(request):
    context = {}
    # edit own profile
    if request.POST:
        data = request.POST
        user = request.user
        user_profile = user.get_profile()
        # set new values to user and user_profile, if key doesn't exist backup to current data
        user.first_name = request.POST.get("first_name", user.first_name)
        user.last_name = request.POST.get("last_name", user.first_name)
        user.save()
        user_profile.company = request.POST.get("company", user_profile.company)
        user_profile.status = request.POST.get("status", user_profile.status)
        user_profile.signature = request.POST.get("signature", user_profile.signature)
        if request.POST.get("public_email", "off") == "on":
            user_profile.public_email = True
        else:
            user_profile.public_email = False
        if request.POST.get("send_notices", "off") == "on":
            user_profile.send_notices = True
        else:
            user_profile.send_notices = False
        user_profile.save()
        context["saved"] = True
    else:
        # fill form with user data
        user = request.user
        try:
            # try to get profile (might not exist yet if user was added by django admin utility)
            user_profile = user.get_profile()
        except UserProfile.DoesNotExist:
            # create empty user profile if it doesn't exist
            user_profile = UserProfile(user=user, key_expires=datetime.today())
            user_profile.save()
        data = {"first_name":user.first_name, "last_name":user.last_name, "company":user_profile.company, "status":user_profile.status, \
        "signature":user_profile.signature, "public_email":user_profile.public_email, "send_notices":user_profile.send_notices}
        context["saved"] = False
    f = ProfileForm(data)
    context["form"] = f
    return render_to_response('portal/edit_profile.html', context, RequestContext(request))
 

# uncomment if you want only registered users to see other profiles   
#@login_required
def view_profile(request, id):
    # view profile
    try:
        # try to get user by id
        user = User.objects.get(id=id)
    except User.DoesNotExist:
        try:
            # if user doesn't exist, try to get it by username
            user = User.objects.get(username__iexact=id)
        except:
            # return user error page
            data = {"doesnotexist":True}
            return render_to_response('portal/view_profile.html', data, RequestContext(request))
    try:
        # try to get user profile (might not exist yet if user was added by django admin utility)
        user_profile = user.get_profile()
    except UserProfile.DoesNotExist:
        # create empty user profile if it doesn't exist
        user_profile = UserProfile(user=user, key_expires=datetime.today())
        user_profile.save()
    public_email = user_profile.public_email
    print public_email
    data = {"username":user.username, "first_name":user.first_name, "last_name":user.last_name, "date_joined":user.date_joined, \
    "status":user_profile.get_status_display(), "company":user_profile.company, "email":user.email, "public_email":public_email}
    return render_to_response('portal/view_profile.html', data, RequestContext(request))
    
